#include <firmware.h>
#include <system.h>
#include <http_download.h>
#include <mqtt_paho.h>

static int gw_upgrade_tag = 0;

static void set_gw_upgrade_tag(void)
{
	gw_upgrade_tag = 1;
}

static int get_gw_upgrade_tag(void)
{
	return gw_upgrade_tag;
}

void clear_gw_upgrade_tag(void)
{
	gw_upgrade_tag = 0;
}


//保存固件描述信息到本地
static void save_firmware_desc(char *url, char *md5sum, char *version)
{
	cJSON *root;
	cJSON *value;
	
	char key_url[64] = {0};
	char key_md5sum[64] = {0};
	char key_version[64] = {0};

	sprintf(key_url, "url");
	sprintf(key_md5sum, "md5sum");
	sprintf(key_version, "version");

	root = parse_root_from_file(FIRMWARE_DESC_FILE);
	if(root)
	{
		//url
		value = cJSON_GetObjectItem(root, key_url);
		if(value)
		{
			cJSON_ReplaceItemInObject(root, key_url, cJSON_CreateString(url));
		}
		else
		{
			cJSON_AddStringToObject(root, key_url, url);
		}

		//md5sum
		value = cJSON_GetObjectItem(root, key_md5sum);
		if(value)
		{
			cJSON_ReplaceItemInObject(root, key_md5sum, cJSON_CreateString(md5sum));
		}
		else
		{
			cJSON_AddStringToObject(root, key_md5sum, md5sum);
		}

		//version
		value = cJSON_GetObjectItem(root, key_version);
		if(value)
		{
			cJSON_ReplaceItemInObject(root, key_version, cJSON_CreateString(version));
		}
		else
		{
			cJSON_AddStringToObject(root, key_version, version);
		}
	}
	else
	{
		//文件不存在
		root = cJSON_CreateObject();
		cJSON_AddStringToObject(root, key_url, url);
		cJSON_AddStringToObject(root, key_md5sum, md5sum);
		cJSON_AddStringToObject(root, key_version, version);
	}
	
	save_root_to_file(root, FIRMWARE_DESC_FILE);
	free_root(root);
}

//从本地获取固件描述信息
static void get_firmware_desc(DEV_FIRMWARE_DESC *firmware_desc, char *filename)
{
	cJSON *root;
	cJSON *value;
	
	char key_url[1024] = {0};
	char key_md5sum[64] = {0};
	char key_version[64] = {0};

	sprintf(key_url, "url");
	sprintf(key_md5sum, "md5sum");
	sprintf(key_version, "version");
	
	root = parse_root_from_file(filename);
	if(root)
	{
		//url
		value = cJSON_GetObjectItem(root, key_url);
		if(value)
		{
			strcpy(firmware_desc->url, value->valuestring);
		}

		//md5sum
		value = cJSON_GetObjectItem(root, key_md5sum);
		if(value)
		{
			strcpy(firmware_desc->md5sum, value->valuestring);
		}

		//version
		value = cJSON_GetObjectItem(root, key_version);
		if(value)
		{
			strcpy(firmware_desc->version, value->valuestring);
		}
		
		free_root(root);
	}
}

//计数文件MD5码判断是否跟md5sum一至
static int firmware_md5_match(char *filename, char *md5sum)
{
	char file_md5sum[256] = {0};
	char cmd[256] = {0};
	int maxline = 1;

	if(!isFileExists(filename))
	{
		DEBUG("%s no exist", filename);
		return -1;
	}

	sprintf(cmd, "md5sum %s", filename);
	myexec(cmd, file_md5sum, &maxline);

	if(strstr(file_md5sum, md5sum))
	{
		DEBUG("%s md5sum ok", filename);
		return 0;
	}
	else
	{
		DEBUG("%s md5sum error", filename);
	}

	return -1;
}

static void cloud_firmware_rsp(int result)
{
	cJSON *root;
	char *out;
	
	root = cJSON_CreateObject();
	cJSON_AddNumberToObject(root, "id", generate_msgid());
	cJSON_AddStringToObject(root, "gwid", get_gw_sn());
	cJSON_AddNumberToObject(root, "ret", result);
	cJSON_AddStringToObject(root, "command", "upgrade");
	out = cJSON_PrintUnformatted(root);
	cJSON_Delete(root);
	gw_publish_setting_rsp_data(out, strlen(out));
	free(out);
}

//解析平台下发固件下载请求
void cloud_firmware_upgrade_req(CLOUD_DATA *cloud_data)
{
	cJSON *value;
	char *url = NULL;
	char *md5sum = NULL;
	char *version = NULL;

	value = cJSON_GetObjectItem(cloud_data->data, "url");
	if(value)
	{
		//DEBUG("url=%s", value->valuestring);
		url = value->valuestring;
	}
	
	value = cJSON_GetObjectItem(cloud_data->data, "md5sum");
	if(value)
	{
		//DEBUG("md5sum=%s", value->valuestring);
		md5sum = value->valuestring;
	}

	value = cJSON_GetObjectItem(cloud_data->data, "version");
	if(value)
	{
		//DEBUG("version=%s", value->valuestring);
		version = value->valuestring;
	}

	if(url == NULL || md5sum == NULL || version == NULL)
	{
		cloud_firmware_rsp(-1);
		return;
	}

	if(strcmp(VERSION, version) >= 0) {
		//cloud_firmware_rsp(-2);
		return;
	}

	//保存固件描述信息到本地
	save_firmware_desc(url, md5sum, version);
	set_gw_upgrade_tag();
	//cloud_firmware_rsp(0);
}

static int firmware_wget_download(void)
{
	int ret;
	char filename[256] = {0};
	DEV_FIRMWARE_DESC firmware_desc = {};
	char command[2048] = {0};

	get_firmware_desc(&firmware_desc, FIRMWARE_DESC_FILE);

	DEBUG("url=%s", firmware_desc.url);
	DEBUG("version=%s", firmware_desc.version);
	DEBUG("md5sum=%s", firmware_desc.md5sum);

	if(http_get_file_name(firmware_desc.url, FIRMWARE_PATH, filename))
	{
		DEBUG("url error");
		return -1;
	}

	if(strcmp(VERSION, firmware_desc.version) >= 0) {
		DEBUG("version same or low");
		return -2;
	}

	//wget --timeout=5 --tries=5 www.juemingt.com/update-v1.0.0.img -O update-v1.0.0.img
	//sprintf(command, "wget --timeout=300 --tries=5 %s -O %s", firmware_desc.url, filename);
	sprintf(command, "curl -o %s --max-time 300 -k -O %s", filename, firmware_desc.url);
	ret = myexec(command, NULL, NULL);
	if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0)
	{
		if(firmware_md5_match(filename, firmware_desc.md5sum))
		{
			DEBUG("firmware md5 error");
			return -3;
		}
		
		DEBUG("firmware md5 ok");
		return 0;
	}
	else
	{
		return -4;
	}
}

static int gw_upgrade(void)
{
	char filename[256] = {0};
	DEV_FIRMWARE_DESC firmware_desc = {};
	char command[1024] = {0};

	get_firmware_desc(&firmware_desc, FIRMWARE_DESC_FILE);
	if(http_get_file_name(firmware_desc.url, FIRMWARE_PATH, filename))
	{
		return -1;
	}

	if(firmware_md5_match(filename, firmware_desc.md5sum))
	{
		return -1;
	}

	sprintf(command, "updateEngine --misc=update --partition=0x2B0100 --reboot --image_url=%s", filename);//0x2B0100 支持uboot boot rootfs oem userdata分区升级
	DEBUG("%s", command);
	myexec(command, NULL, NULL);
	return 0;
}

//从U盘升级固件
static void update_img_from_udisk_detect(void)
{
	char *firmware_file = "/userdata/udisk/update.img";
	char *desc_file = "/userdata/udisk/firmware_desc.json";

	DEV_FIRMWARE_DESC firmware_desc = {};
	char command[1024] = {0};

	if(!isFileExists(desc_file) || !isFileExists(firmware_file)) {
		return;
	}

	get_firmware_desc(&firmware_desc, desc_file);

	if(strcmp(VERSION, firmware_desc.version) >= 0) {
		return;
	}

	if(firmware_md5_match(firmware_file, firmware_desc.md5sum))
	{
		return;
	}

	sprintf(command, "updateEngine --misc=update --partition=0x2B0100 --reboot --image_url=%s", firmware_file);//0x2B0100 支持uboot boot rootfs oem userdata分区升级
	DEBUG("%s", command);
	myexec(command, NULL, NULL);
}

//从U盘升级 expand 固件
static void update_expand_img_from_udisk_detect(void)
{
	char *firmware_file = "/userdata/udisk/update_expand.img";
	char *desc_file = "/userdata/udisk/firmware_desc_expand.json";

	DEV_FIRMWARE_DESC firmware_desc = {};
	char command[1024] = {0};

	if(!isFileExists(desc_file) || !isFileExists(firmware_file)) {
		return;
	}

	get_firmware_desc(&firmware_desc, desc_file);

	if(strcmp(VERSION, firmware_desc.version) >= 0) {
		return;
	}

	if(firmware_md5_match(firmware_file, firmware_desc.md5sum))
	{
		return;
	}

	sprintf(command, "updateEngine --misc=update --partition=0x2B0100 --reboot --image_url=%s", firmware_file);
	DEBUG("%s", command);
	myexec(command, NULL, NULL);
}

static void* firmware_download_upgrade_thread(void *arg)
{
	int ret;

	update_img_from_udisk_detect();
	update_expand_img_from_udisk_detect();

	while(1)
	{
		if(get_gw_upgrade_tag())
		{
			ret = firmware_wget_download();
			cloud_firmware_rsp(ret);
			if(ret == 0)
			{
				second_sleep(5);gw_upgrade();
			}
			clear_gw_upgrade_tag();
		}
	
		second_sleep(5);
	}
	return NULL;
}

void firmware_ota_init(void)
{
	create_thread(firmware_download_upgrade_thread, NULL);
}

